/**
 * @name AvatarUploader
 * @author darcrand
 * @desc 头像上传组件
 */

import React, { Component } from 'react'
import { Upload, message } from 'antd'
import uuid from 'uuid'
import { CloudUploadOutlined } from '@ant-design/icons'
import styles from './styles.module.less'

const defaultProxy = process.env.REACT_APP_DEFAULT_PROXY

function getBase64Url(img) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.addEventListener('load', () => resolve(reader.result))
    reader.addEventListener('error', () => reject('图片加载错误'))
    reader.readAsDataURL(img)
  })
}

class AvatarUploader extends Component {
  /**
   * @prop {string|object} value 绑定的图片,可能是url路径或文件对象
   * @prop {string|object} defaultValue 默认值
   * @prop {boolean} disabled 是否禁用
   * @prop {function} onChange 修改要上传的图片时触发
   */
  static defaultProps = {
    value: undefined,
    defaultValue: undefined,
    disabled: false,
    onChange: value => {},
  }

  state = {
    value: undefined,
    lastValue: undefined,

    // Upload组件使用的数据
    fileList: [],

    // 用来显示的图片url
    displayImageUrl: undefined,
  }

  componentDidUpdate() {
    // 父组件>包裹组件>Upload组件 数据映射
    if (this.props.value !== this.state.lastValue) {
      const newValue = this.props.value

      // 把传入的数据转化成'Upload'组件使用的格式
      let fileList = []
      if (typeof newValue === 'string' && newValue.length > 0) {
        // 原始url类型
        fileList = [{ uid: uuid(), name: newValue.split('/').pop(), status: 'done', url: newValue }]
      } else if (typeof newValue === 'object' && newValue.size) {
        // 被修改成文件对象
        fileList = [newValue]
      }

      // 计算显示的图片
      this.onUpdateDisplayImage(newValue)

      this.setState({ value: newValue, lastValue: newValue, fileList })
    }
  }

  onImageChange = ({ file }) => {
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
    if (!isJpgOrPng) {
      message.error('请上传 jpg/png 格式的图片')
      return
    }
    const isLt2M = file.size / 1024 / 1024 < 2
    if (!isLt2M) {
      message.error('图片大小不能超过 2M')
      return
    }
    this.props.onChange && this.props.onChange(file)
  }

  onUpdateDisplayImage = async (img = '') => {
    try {
      let displayImageUrl = null
      if (typeof img === 'string' && img.length > 0) {
        displayImageUrl = defaultProxy + img
      } else if (typeof img === 'object' && img.size) {
        displayImageUrl = await getBase64Url(img)
      }
      this.setState({ displayImageUrl })
    } catch (err) {
      message.error(err)
    }
  }

  render() {
    const { fileList, displayImageUrl } = this.state

    return (
      <Upload
        beforeUpload={() => false}
        accept='image/jpeg,image/png'
        listType='picture-card'
        showUploadList={false}
        disabled={this.props.disabled}
        fileList={fileList}
        onChange={this.onImageChange}
      >
        {displayImageUrl ? (
          <div className={styles.img} style={{ backgroundImage: `url("${displayImageUrl}")` }} />
        ) : (
          <div>
            <CloudUploadOutlined style={{ fontSize: 32 }} />
            <div>upload image</div>
          </div>
        )}
      </Upload>
    )
  }
}

export default AvatarUploader
